#include <audio/MIDI/MIDIMusicDeviceWin32.h>
#include <system/Log.h>

#if NE_PLATFORM == NE_PLATFORM_WINDOWS

namespace ne
{
    MIDIMusicDeviceWin32::MIDIMusicDeviceWin32()
        : MIDIOutDevice(0, "MIDI Music Device Win32")
    {
        _create();
    }

    bool MIDIMusicDeviceWin32::open()
    {
        if (isOpen()) return true;

        MIDIOUTCAPS outCaps;
        for (uint32_t i=0; i<midiOutGetNumDevs(); ++i)
        {
            midiOutGetDevCaps(i, &outCaps, sizeof(MIDIOUTCAPS));
            Log::Out("MIDI OUT CAPS[%d, %s]", i, outCaps.szPname);
        }
        midiOutOpen(&mOutDeviceHandle, MIDI_MAPPER, 0, 0, CALLBACK_NULL);
        Log::Out("MIDIMusicDeviceWin32[0x%x]", mOutDeviceHandle);
        mIsOpen = true;

        return true;
    }

    bool MIDIMusicDeviceWin32::reset()
    {
        midiOutReset(mOutDeviceHandle);
        return true;
    }

    bool MIDIMusicDeviceWin32::close()
    {
        if (!isOpen()) return true;

        midiOutClose(mOutDeviceHandle);
        mIsOpen = false;

        return false;
    }

    bool MIDIMusicDeviceWin32::sendEvent(const byte event, const byte parameter1, const byte parameter2)
    {
        DWORD dwMsg = event | (parameter1 << 8) | (parameter2 << 16);
        MMRESULT result = midiOutShortMsg(mOutDeviceHandle, dwMsg);
        if (result != MMSYSERR_NOERROR)
        {
            Log::Out(LL_WARNING, "MIDIMusicDeviceWin32::sendEvent Error");
            return false;
        }
        return true;
    }

    bool MIDIMusicDeviceWin32::sendSysExEvent(const byte *buffer, const uint32_t length)
    {
        /*
        MIDIHDR outHdr;
        outHdr.lpData = buffer;
        outHdr.dwBufferLength = length;
        outHdr.dwBytesRecorded = length;
        MMRESULT result = midiOutLongMsg(mOutDeviceHandle, &outHdr, length);
        if (result != MMSYSERR_NOERROR)
        {
            Log::Out(LL_WARNING, "MIDIMusicDeviceWin32::sendSysExEvent Error");
            return false;
        }
        */
        return true;
    }

    MIDIMusicDeviceWin32::~MIDIMusicDeviceWin32()
    {
        _destroy();
    }

    bool MIDIMusicDeviceWin32::_create()
    {
        return true;
    }

    bool MIDIMusicDeviceWin32::_destroy()
    {
        return close();
    }
}

#endif
